#include "../logs/bitlog.h"
using namespace bitlog;

#include <vector>
#include <thread>
#include <chrono>

void bench(const std::string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 获取日志器
    Logger::ptr logger = getLogger(logger_name);
    if(logger.get() == nullptr) return;
    std::cout << "测试日志: " << msg_count << "条，总大小: " << (msg_count * msg_len) / 1024  << "KB" << std::endl;

    // 组织指定长度的日志消息
    std::string msg(msg_len - 1, 'T'); // 少一个字节，给末尾添加换行

    // 创建指定数量的线程
    std::vector<std::thread> threads;
    std::vector<double> cost_arr(thr_count);
    size_t msg_per_thr = msg_count / thr_count; // 每个线程要写的日志数量
    for(int i = 0; i < thr_count; ++i)
    {
        threads.emplace_back([&, i]()
        {
            // 线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            
            // 开始循环写日志
            for(int j = 0; j < msg_per_thr; ++j) logger->fatal("s", msg);

            // 线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            cost_arr[i] = cost.count();
            std::cout << "线程" << i << ": \t输出日志数量: " << msg_per_thr << ", 耗时: " << cost.count() << std::endl;
        });
        
    }
    for(int i = 0; i < thr_count; ++i) threads[i].join();

    // 计算总耗时---在多线程中，每个线程都会耗费时间，但是线程是并发处理的，因此耗时最多的那个就是总时间
    double max_cost = cost_arr[0];
    for(int i = 1; i < thr_count; ++i) max_cost = max_cost > cost_arr[i] ? max_cost : cost_arr[i];
    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);

    // 进行输出打印
    std::cout << "每秒输出日志数量: " << msg_per_sec << "条" << std::endl;
    std::cout << "每秒输出日志大小: " << msg_per_sec << "KB" << std::endl;

}

void sync_bench() // 同步
{
    std::unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->buildLoggerType(LoggerType::LOGGER_SYNC);
    builder->buildLoggerName("Sync_logger");
    builder->buildLoggerLevel(LogLevel::lev::DEBUG);
    builder->buildFormatter("%m%n");
    builder->buildSink<FileSink>("./logfile/test.log");
    builder->build();

    bench("Sync_logger", 1, 1000000, 100); // 单线程
    // bench("Sync_logger", 3, 1000000, 100); // 多线程
}

void async_bench() // 异步
{
    std::unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->buildLoggerType(LoggerType::LOGGER_ASYNC);
    builder->buildLoggerName("Async_logger");
    builder->buildLoggerLevel(LogLevel::lev::DEBUG);
    builder->buildFormatter("%m%n");
    builder->buildSink<FileSink>("./logfile/test.log");
    builder->build();

    // bench("Async_logger", 1, 1000000, 100);
    bench("Async_logger", 3, 1000000, 100);
}

int main()
{
    // sync_bench();
    async_bench();

    return 0;
}